/**
* AutoSWF - Cody Cushing. March 26, 2009
* Copyright (c) 2009 Cody Cushing
* No use restrictions. Maintain this notice in all versions. 
**/

package com.autoswf.core
{
	import flash.utils.Dictionary;
	
	/**
	 * Supports automating an event handler without using a ChainLinkSprite. Especially useful 
	 * when altering the target dispatcher object is not feasible, but tracking and automation 
	 * for that object is still desired. 
	 * 
	 * TO DO: figure out how to handle losing the proxy function reference when the same function 
	 * proxied a second time. 
	 */	
	public class HandlerObserver
	{
		private var chainLink:IChainLink;
		private var handlers:Dictionary
		
		/**
		 * This class requires a link to the automation tree, pass the client's node here. 
		 * 
		 * @param chainLink  The entry point in the chain for bubbling and recieving automation events. 
		 */		
		public function HandlerObserver(chainLink:IChainLink)
		{
			this.chainLink = chainLink;
			handlers = new Dictionary(true);
		}
		
		/**
		 * Use this function in a controller when attaching listeners to components in a 
		 * view. 
		 * 
		 * @param handler  The event handler for this event
		 * @return         A function that splices automation support between the 
		 * event and the handler
		 */		
		public function spy(handler:Function):Function
		{
			if(handlers[handler] == null)
			{
				handlers[handler] = function(event:*):void
				{
					chainLink.sendUpChain(event);	/* Bubble events up */
					handler(event);				/* Invoke handler */
				}
			}
			
			return handlers[handler];
		}
		
		/**
		 * Delete the reference to the proxy function and return the reference so it can be removed 
		 * from any dispatcher.
		 * 
		 * @param handler  The event handler for this event
		 * @return         A function that splices automation support between the
		 * event and the handler
		 */		
		public function killSpy(handler:Function):Function
		{
			var func:Function = handlers[handler];
			delete handlers[handler];
			return func;
		}

	}
}